package cn.ly.jdkset;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;

public class MainTest {
	
	public static void main(String[] args) {
		
		List l;
		
		ArrayList al = new ArrayList(20); //底层是用Object[] + E 泛型实现
		/**
		 * ArrayList底层是用Object[]实现的，与hashmap一样的道理，它的默认初始值是10，如果我们插入的值大于10了，
		 * ArrayList就会自动增长，由于数组本身是不能增长的，所以这种增长的方式就是copy出新的数组，这样也是浪费了空间和时间的。
		 * 所以对于集合的使用应该具有通用性，预先估算或者确定数据容量，用于初始化确定集合的空间大小，避免自动增长消耗的性能。
		 * 对于ArrayList的自动增长，是非常浪费的，因为当超过初始化容量10后，每次项集合中保存数据，list都会自动增长依次，也就是
		 * 复制依次数组，这个是非常不必要的。
		 * Vector，Stack，都属于底层是数组的实现，原理一样
		 */
		
		LinkedList ll;//底层是 Node（pre，next）节点，first，last，双端双向链表，add的插入是从尾端插入链表的
		
		Vector v;     //底层是Object[] + E 泛型，特点：方法加了synchronized同步
		
		Stack s;      //是Vector的子类，底层是Object[]
		
//－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－
		
		Set set;
		
		HashSet hs;   //底层是一个HashMap，底层的HashMap用entry来保存数据（也就是map中的key来保存HashSet的值，所有的value 保存的都是一个new Object()常量）
		
		TreeSet ts;   //NavigableMap接口的子类，可能是TreeMap
		
		LinkedHashSet lhs;
		/**
		 * LinkedHashSet继承了HashSet，其内部实现使用的是LinkedHashMap，实现原理与LinkedHashMap类似，
		 * 只是它只保存key，value是一个final的new Object()
		 */
		
//－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－
		
		Map map;
		
		/**
		 * 底层是Node<K,V>保存key/value值，Node<K,V>实现了Map.Entry<K,V>底层是一个Node<K,V>[] table，
		 * 而 table 实际上是一个Node类型的数组，数组下标是通过hash计算出来的
		 * 这个Node类型有一个next引用指针，当hash计算出来的数组下标相同时，这个索引下标的位置保存的还是一个Node，
		 * 但是，其中保存了两个元素，一个是原有的Node1，还有一个是新的Node2，Node1的next引用指向了新的Node2
		 * 这样的方式解决hash值相同导致的数据重复，但都能保存。
		 * 这是使用的发生冲突时，使用链式地址的方式来解决冲突
		 * 
		 * Node<K,V> implements Map.Entry<K,V>{
		 * 		final int hash;当前node的计算出的hash值；
        		final K key;   当前node的key
        		V value;       当前node的value
        		Node<K,V> next;当前node的next指针，当发生冲突时，用链式地址的方式解决冲突问题，
        		用next指向hash值相同的那个node，来保存这个node
		 * 
		 * }
		 */
		HashMap hm = new HashMap<String,String>(20);
		/**
		 * 当我们预先直到需要将多少数据存放到 hashmap中时，需要设定它的初始值，因为hashmap的默认初始值是16，
		 * 如果我们需要存放20个数据项时，则当存放数量超过16*0.75时，hashmap就会resize()依次，扩容，这个是非常消耗性能的，
		 * 所以为了，减少resize()的次数，最好预先设定号需要存放到hashmap中数据的个数，然后进行map的初始化。
		 * ConcurrentHashMap 原理一样
		 */
		
		/**
		 * resize，扩容，newTab[e.hash & (newCap - 1)] = e;-->会把原有数据按照新的集合容量重新做依次散列分配，这个过程是非常耗时的。
		 */
		
		LinkedHashMap lhm = new LinkedHashMap();
		lhm.put("1", "test1");
		lhm.put("1", "test2");
		
		HashMap hm1 = new HashMap();
		hm1.put("1", "hm1");
		hm1.put("1", "hm2");
		
		
		
		System.out.println(lhm);
		System.out.println(hm1);
		
		/**
		 * LinkedHashMap继承了HashMap，同时右维护了一个链表，这个链表可以保证存储进来的值的顺序不变，但是如果只有链表进行值的保存，
		 * 那么插入时，就必须遍历全链表，查看是否有相同的元素，这样效率太低了。所以又它用了hash表来全部元素，这样当插入时就可以提升插入速度

			插入步骤：
			1、先把数据通过HashMap的方式进行处理。
			2、调用afterNodeAccess方法，此方法在HashMap中是空方法，在LinkedHashMap就有实现了，
			        它会把整个链表的tail指针指向这个节点。
		 */
		
		TreeMap tm;//底层是Entry<K,V>，是一个红黑树（自平衡的二叉查找树）
		/**
		 * TreeMap底层是用红黑树实现的，红黑树是一个自平衡的二叉查找树。TreeMap插入时，先按照二叉查找树的规则进行插入，
		 * 即先是让左子节点最小，父节点次之，右子节点最大。按照这种方式插入之后，再调整树的颜色。
		 */
		
		ConcurrentHashMap chm = new ConcurrentHashMap();//底层是Node<K,V>[] table;类似HashMap，主要是有同步功能，与Executors框架 合作使用
		
		chm.put("", "");
		

	}
	
	

}
